package org.rc.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.rc.model.Result;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.api.datastore.QueryResultIterator;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.googlecode.objectify.Query;
import java.util.Map;
import org.rc.dao.RaceDao;
import org.rc.dao.ResultDao;
import org.rc.model.Race;
import static com.google.appengine.api.taskqueue.TaskOptions.Builder.*;

/**
 * Update the counts of race results in a {@link Race}
 * @author dokeeffe
 */
public class UpdateRaceResultCountTask extends Task {

    private static final Logger LOGGER = LoggerFactory.getLogger(UpdateRaceResultCountTask.class);

    private RaceDao raceDao = new RaceDao();
    private ResultDao resultDao = new ResultDao();

    @Override
    public void run(Map parameterMap) {
        long startTime = System.currentTimeMillis();
        String fromCursor = (String) parameterMap.get("fromCursor");
        Query q = raceDao.ofy().query(Race.class);
        if(fromCursor!=null)
            q.startCursor(Cursor.fromWebSafeString(fromCursor));
        QueryResultIterator<Race> iterator = q.iterator();
        LOGGER.info("Starting to iterate over races");
        while(iterator.hasNext()) {
            Race race = iterator.next();
            if(race.getNumberOfResults()==null || race.getNumberOfResults()<1) {
                LOGGER.info("calculating for race " + race.getName());
                Query rq = resultDao.ofy().query(Result.class);
                rq.filter("race", race);
                race.setNumberOfResults(rq.count()); //nasty
                raceDao.put(race);
            }
            if (System.currentTimeMillis() - startTime > LIMIT_MILLIS) {
                resubmit(iterator.getCursor().toWebSafeString());
                return;
            }
        }
        LOGGER.info("Complete");
        
    }

    private void resubmit(String fromCursor) {
        LOGGER.info("Resubmitting at " + fromCursor);
        Queue queue = QueueFactory.getDefaultQueue();
        queue.add(withUrl("/admin?task=" + getTaskName() + "&fromCursor="+fromCursor).method(Method.GET));
    }

    @Override
    public String getUiName() {
        return "Update Results Counts";
    }

}
